<!--
  智慧社区管理系统 - 批量退款对话框组件
  @author Wu.Liang
  @date 2025-06-26
  @version 3.0 - 根据系统设计调整方案重构，统一支付接口
-->
<template>
  <el-dialog
    v-model="dialogVisible"
    title="批量退款"
    width="600px"
    :close-on-click-modal="false"
  >
    <div class="batch-refund-form">
      <!-- 选中记录信息 -->
      <el-card class="info-card" shadow="never">
        <template #header>
          <div class="card-header">
            <span>选中记录信息</span>
            <el-tag type="info">{{ selectedRows.length }} 条记录</el-tag>
          </div>
        </template>
        
        <div class="selected-summary">
          <div class="summary-item">
            <span class="label">总支付金额：</span>
            <span class="amount">¥{{ totalAmount }}</span>
          </div>
          <div class="summary-item">
            <span class="label">可退款金额：</span>
            <span class="refundable-amount">¥{{ refundableAmount }}</span>
          </div>
        </div>

        <el-table :data="selectedRows" border stripe style="width: 100%; margin-top: 15px;">
          <el-table-column prop="orderNo" label="订单号" width="180" />
          <el-table-column prop="userName" label="用户" width="100" />
          <el-table-column prop="amount" label="支付金额" width="120">
            <template #default="{ row }">
              <span class="amount">¥{{ row.formattedAmount }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="paymentMethodName" label="支付方式" width="100" />
          <el-table-column prop="paymentStatusName" label="状态" width="100">
            <template #default="{ row }">
              <el-tag :type="getStatusTagType(row.paymentStatus)">
                {{ row.paymentStatusName }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>
      </el-card>

      <!-- 退款表单 -->
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
        @submit.prevent
      >
        <el-form-item label="退款方式" prop="refundType">
          <el-radio-group v-model="form.refundType" @change="handleRefundTypeChange">
            <el-radio value="full">全额退款</el-radio>
            <el-radio value="partial">部分退款</el-radio>
            <el-radio value="custom">自定义金额</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item v-if="form.refundType === 'custom'" label="退款金额" prop="refundAmount">
          <el-input-number
            v-model="form.refundAmount"
            :min="0.01"
            :max="refundableAmount"
            :precision="2"
            :step="0.01"
            style="width: 100%"
            placeholder="请输入退款金额"
          />
          <div class="form-tip">
            最大可退款金额：¥{{ refundableAmount }}
          </div>
        </el-form-item>

        <el-form-item label="退款原因" prop="refundReason">
          <el-select
            v-model="form.refundReason"
            placeholder="请选择退款原因"
            style="width: 100%"
            @change="handleReasonChange"
          >
            <el-option label="用户主动申请" value="用户主动申请" />
            <el-option label="系统错误" value="系统错误" />
            <el-option label="重复支付" value="重复支付" />
            <el-option label="服务未提供" value="服务未提供" />
            <el-option label="其他原因" value="其他原因" />
          </el-select>
        </el-form-item>

        <el-form-item v-if="form.refundReason === '其他原因'" label="具体原因" prop="customReason">
          <el-input
            v-model="form.customReason"
            type="textarea"
            :rows="3"
            placeholder="请输入具体退款原因"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>

        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息（可选）"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
      </el-form>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="loading">
          确认批量退款
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import type { PaymentVO } from '../types/payment'
import { showWarning } from '@/utils/message'

// 作者: Wu.Liang

// Props
interface Props {
  modelValue: boolean
  selectedRows: PaymentVO[]
  loading?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  loading: false
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'confirm': [data: { 
    paymentIds: number[]
    refundAmount: number
    refundReason: string
    remark?: string
  }]
}>()

// 响应式数据
const formRef = ref<FormInstance>()

// 表单数据
const form = reactive({
  refundType: 'full',
  refundAmount: 0,
  refundReason: '',
  customReason: '',
  remark: ''
})

// 表单验证规则
const rules: FormRules = {
  refundType: [
    { required: true, message: '请选择退款方式', trigger: 'change' }
  ],
  refundAmount: [
    { required: true, message: '请输入退款金额', trigger: 'blur' },
    { type: 'number', min: 0.01, message: '退款金额必须大于0', trigger: 'blur' }
  ],
  refundReason: [
    { required: true, message: '请选择退款原因', trigger: 'change' }
  ],
  customReason: [
    { required: true, message: '请输入具体退款原因', trigger: 'blur' }
  ]
}

// 计算属性
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const totalAmount = computed(() => {
  return props.selectedRows.reduce((sum, row) => sum + row.amount, 0).toFixed(2)
})

const refundableAmount = computed(() => {
  return props.selectedRows
    .filter(row => row.canRefund && !row.isRefunded)
    .reduce((sum, row) => sum + row.amount, 0)
    .toFixed(2)
})

// 监听器
watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    resetForm()
  }
})

// 方法
const resetForm = () => {
  Object.assign(form, {
    refundType: 'full',
    refundAmount: Number(refundableAmount.value),
    refundReason: '',
    customReason: '',
    remark: ''
  })
  formRef.value?.clearValidate()
}

const handleRefundTypeChange = () => {
  if (form.refundType === 'full') {
    form.refundAmount = Number(refundableAmount.value)
  } else if (form.refundType === 'partial') {
    form.refundAmount = Number(refundableAmount.value) * 0.5
  }
}

const handleReasonChange = () => {
  if (form.refundReason !== '其他原因') {
    form.customReason = ''
  }
}

const handleClose = () => {
  dialogVisible.value = false
}

const handleConfirm = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    
    const refundReason = form.refundReason === '其他原因' 
      ? form.customReason 
      : form.refundReason
    
    const paymentIds = props.selectedRows
      .filter(row => row.canRefund && !row.isRefunded)
      .map(row => row.id)
    
    if (paymentIds.length === 0) {
      showWarning('没有可退款的支付记录')
      return
    }
    
    emit('confirm', {
      paymentIds,
      refundAmount: form.refundAmount,
      refundReason,
      remark: form.remark
    })
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}

// 工具方法
const getStatusTagType = (status: number) => {
  const typeMap = {
    1: 'warning',
    2: 'primary',
    3: 'success',
    4: 'danger',
    5: 'info'
  }
  return typeMap[status as keyof typeof typeMap] || 'info'
}
</script>

<style scoped>
.batch-refund-form {
  max-height: 600px;
  overflow-y: auto;
}

.info-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  color: #303133;
}

.selected-summary {
  display: flex;
  gap: 20px;
  margin-bottom: 15px;
}

.summary-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.label {
  color: #606266;
  font-size: 14px;
}

.amount {
  font-weight: 600;
  color: #67c23a;
  font-size: 16px;
}

.refundable-amount {
  font-weight: 600;
  color: #409eff;
  font-size: 16px;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.dialog-footer {
  text-align: right;
}
</style> 